package com.lz.ub.hm

import android.os.Handler
import android.os.Looper
import android.os.Message
import com.lz.ub.Logger
import java.lang.ref.WeakReference
import java.util.*

/**
 * @author you
 * 蓝牙连接器
 */
internal class UBConnection(private val ubCommand: UBCommand) {

    private val handler by lazy { CommandHandler(this) }

    private val deviceList = LinkedList<UBDevice>()

    private var current: UBDevice? = null

    fun isAvailable(): Boolean = deviceList.isEmpty() && current == null

    fun isExecuting(): Boolean = current != null
    //处理的是连接的状态
    private var isConnectingState = true

    private fun delayNext() {
        handler.sendEmptyMessageDelayed(MSG_NEXT, COMMAND_BUFFER_TIME)
    }

    private fun next() {
        Logger.i(UBCommand.TAG, "next ---------------------")
        next(isConnectingState)
    }

    private fun next(isConn: Boolean) {
        current = deviceList.pollFirst()
        if (current != null) {
            val device = current!!
            if (isConn) {
                when (device.status) {
                    STATUS_INIT -> ubCommand.write(device.connectCommand)
                    STATUS_CONNECTED -> ubCommand.write(device.propertyCommand)
                    else -> next(true)
                }
            } else { //断开时
                ubCommand.write(device.disconnectCommand)
            }
        } else {
            ubCommand.complete()
        }
    }

    //超时, 此时要断开这台设备
    private fun timeout() {
        Logger.i(UBCommand.TAG, "timeout ............. ---------")
        if (current != null) {
            current!!.status = STATUS_INIT
            ubCommand.write(current!!.disconnectCommand)
//            delayNext() 这里等待超时后的指令响应
        } else {
            next()
        }
    }

    private fun delayProperty() {
        if (current != null) {
            ubCommand.write(current!!.propertyCommand)
        } else {
            next(true)
        }
    }

    //推入前过滤掉设备状态
    fun pushConnection(devices: List<UBDevice>): Boolean {
        if (deviceList.isNotEmpty() || devices.isEmpty()) return false
        deviceList.addAll(devices)
        isConnectingState = true
        next()
        return true
    }

    fun pushConnection(device: UBDevice): Boolean {
        if (deviceList.isNotEmpty()) return false
        deviceList.add(device)
        isConnectingState = true
        next()
        return true
    }

    //推入前过滤掉设备状态
    fun pushDisconnection(devices: List<UBDevice>): Boolean {
        if (deviceList.isNotEmpty() || devices.isEmpty()) return false
        deviceList.addAll(devices)
        isConnectingState = false
        next()
        return true
    }

    fun pushDisconnection(device: UBDevice): Boolean {
        if (deviceList.isNotEmpty()) return false
        deviceList.add(device)
        isConnectingState = false
        next()
        return true
    }

    fun connectCallback(isConn: Boolean, status: Int) {
        if (status == SUCCESS) {
            current?.status = STATUS_CONNECTING
            handler.sendEmptyMessageDelayed(MSG_TIMEOUT, ubCommand.connectTimeout)
        } else {
            Logger.i(UBCommand.TAG, "disconnect connect")
            delayNext()
        }
    }

    fun serviceCallback(status: Int, link: Int): Boolean {
        Logger.i(UBCommand.TAG, "serviceCallback... $link, ${current?.link}")
        handler.removeMessages(MSG_TIMEOUT)
        if (current != null && current!!.link == link) {
            if (status == SUCCESS) {
                current!!.status = STATUS_CONNECTED
                Logger.i(UBCommand.TAG, "delay serviceCallback...")
                handler.sendEmptyMessageDelayed(MSG_PROPERTY, COMMAND_BUFFER_TIME)
            } else { //断开连接
                current!!.status = STATUS_INIT
                Logger.i(UBCommand.TAG, "delay next...")
                delayNext()
            }
            return true
        }
        return false
    }

    fun propertyCallback(status: Int) {
        if (status == SUCCESS) {
            current?.status = STATUS_SERVING
        }
        delayNext()
    }

    fun errorCallback() {
        delayNext()
    }

    //强制关闭
    fun clear() {
        handler.removeMessages(MSG_NEXT)
        handler.removeMessages(MSG_TIMEOUT)
        deviceList.clear()
        current = null
    }

    companion object {
        //延时消息
        private const val MSG_NEXT = 1
        //属性延时消息
        private const val MSG_PROPERTY = 2
        //超时消息
        private const val MSG_TIMEOUT = 3
    }

    private class CommandHandler(connection: UBConnection) : Handler(Looper.getMainLooper()) {

        val reference = WeakReference(connection)

        override fun handleMessage(msg: Message) {
            when (msg.what) {
                MSG_NEXT -> reference.get()?.next()
                MSG_PROPERTY -> reference.get()?.delayProperty()
                MSG_TIMEOUT -> reference.get()?.timeout()
            }
        }

    }
}